/* eslint-disable react/display-name */
import React, { Component } from 'react'

import { Select, message, Table, Spin, Tooltip } from 'antd'
import { address } from '@/Utils/apiConfig'
import getData from '@/Utils/fecth'
import { CaretDownOutlined, DoubleRightOutlined } from '@ant-design/icons'
import moment from 'moment'
import _ from 'lodash'

import { APP_TIMESTAMP_FORMAT } from '@/Utils/CONST'
import { STATUSCLASS } from '@/Utils/CONST.js'
import IconFont from '@/components/IconFont'
import SearchInput from '@/components/SearchInput'

import './index.less'

const { leagueManagement: { getChannelListAll }} = address
const { monitor: { queryOverview, recentBlock, recentTx, searchData }} = address
const { Option } = Select

class BlockchainBrowser extends Component {
  constructor(props) {
    super(props)
    this.state = {
      consortiumId: props.match.params.id,
      consortiumName: props.match.params.name,
      defaultChannel: '',
      pageNum: 1,
      pageSize: 5,
      channelList: [],
      loadingB: false,
      loaddingTx: false,
      overviewData: null,
      channelId: '',
      overviewConf: [
        {
          label: '名称',
          params: 'display_name',
        },
        {
          label: '运行状态',
          params: 'consortiumStatus',
        },
        {
          label: '通道名称',
          params: 'channelName',
        },
        {
          label: '创建时间',
          params: 'createTime',
        },
        {
          label: <span style={{ display: 'flex', alignItems: 'center' }}>区块生成时间
            <Tooltip arrowPointAtCenter placement="top" title={'通道运行总时长/已出的区块数'}>
              <IconFont className="cursor warn" type="ic-tishi1" style={{ marginLeft: '4px', fontSize: '14px' }} />
            </Tooltip>
          </span>,
          params: 'blockSpeed',
        },
      ],
      cardConf: [
        {
          icon: require('@/images/browser/node.svg'),
          label: '节点数量',
          params: 'nodeNum',
        },
        {
          icon: require('@/images/browser/tx.svg'),
          label: '交易数量',
          params: 'tx_number',
        },
        {
          icon: require('@/images/browser/block.svg'),
          label: '区块数量',
          params: 'blockNum',
        },
        {
          icon: require('@/images/browser/chaincode.svg'),
          label: '合约数量',
          params: 'chaincodeNum',
        },
      ],
      tableConf: [
        {
          key: 'id',
          type: 'block',
          title: '最新区块',
          dataName: 'blockData',
          cloumn: 'blockCloumn',
          loading: 'bLoading',
          total: 'blockTotalNum',
        },
        {
          key: 'id',
          type: 'tx',
          title: '最新交易',
          dataName: 'txData',
          cloumn: 'txCloumn',
          loading: 'tLoading',
          total: 'txTotalNum',
        },
      ],
      blockCloumn: blockCloumn,
      txCloumn: txCloumn,
      overviewLoading: false,
      blockTotalNum: 0,
      txTotalNum: 0,
    }
  }

  async componentDidMount() {
    this.cancelScale()
    let channelData = await this.getChannelList()

    if (channelData && channelData.length) {
      this.queryOverview()
      this.getRecentBlock()
      this.getRecentTx()
    }
  }

  // 还原页面缩放
  cancelScale = () => {
    document.getElementById('body').style.width = '100%'
    document.getElementById('body').style.height = '100%'
    document.getElementById('body').style.transformOrigin = 'unset'
    document.getElementById('body').style.transform = 'unset'
    document.getElementById('body').style.marginTop = '0'
    document.getElementById('body').style.marginLeft = '0'
  }

  changeChannel = (value) => {
    const { channelList } = this.state
    let arr = channelList.filter(item => item.name === value)
    let channelId = arr.length && arr[0].id
    this.setState({
      channelId,
      defaultChannel: value,
    }, () => {
      this.queryOverview()
      this.getRecentBlock()
      this.getRecentTx()
    })
  }

  // 获取通道列表
  getChannelList = async() => {
    const { consortiumId } = this.state
    let data = null
    await getData().get(getChannelListAll.format({ consortiumId })).then(res => {
      switch (res.status) {
      case 200:
        data = res.data.channels || []
        this.setState({
          channelList: data,
          defaultChannel: data.length && data[0].name || '',
          channelId: data.length && data[0].id || '',
        })
        break
      default:
        message.error('请求失败')
        break
      }
    })
    return data
  }

  queryNoHash = (param) => {
    if (!param) return false
    const { consortiumId, channelId, consortiumName, defaultChannel } = this.state
    if (!defaultChannel) {
      return message.warn('请先选择通道名称')
    }
    let options = ''
    let type = ''
    let pathname = ''

    if (!isNaN(+param)) {
      // 输入为No. 搜索结果是区块
      type = 'block'
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/blockDetail/${channelId}/${param}`
      options = {
        type,
        channelName: defaultChannel,
        height: Number(param),
      }
    } else {
      // 搜索结果是交易
      type = 'tx'
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/transactionsDetail/${channelId}/${param}`
      options = {
        type,
        txHash: param,
        channelName: defaultChannel,
      }
    }

    getData().post(searchData.format({ consortiumId }), options).then(res => {
      const status = res.status
      switch (status) {
      case 200: {
        const data = res.data
        this.props.history.push({
          pathname,
          state: {
            type,
            data,
          },
        })
        break
      }
      case 409:
        message.error('搜索的区块或交易不存在')
        break
      default:
        message.error('搜索失败')
        break
      }
    })
  }

  setLoadingState = (varName, state) => {
    this.setState({
      [varName]: state,
    })
  }

  // 获取概览信息
  queryOverview = () => {
    const { consortiumId, channelId } = this.state
    this.setLoadingState('overviewLoading', true)
    const options = {
      consortiumId: consortiumId,
      channelId: channelId,
    }
    getData().get(queryOverview.format(options)).then(res => {
      if (res.status === 200) {
        const data = res.data
        data.consortiumConf = 'Fabric'
        data.createTime = moment(data.createTime).format('YYYY-MM-DD HH:mm:ss')
        this.setState({
          overviewData: res.data,
        })
      }
      this.setLoadingState('overviewLoading', false)
    })
  }

  getRecentBlock = () => {
    const { consortiumId, channelId, pageNum, pageSize } = this.state
    this.setState({
      bLoading: true,
    })
    getData().get(recentBlock.format({ consortiumId, channelId, pageNum, pageSize })).then(res => {
      if (res.status === 200) {
        this.setState({
          blockData: res.data.blocks || [],
          bLoading: false,
          blockTotalNum: res.data.totalNum,
        })
      }
    })
  }

  getRecentTx = () => {
    const { consortiumId, channelId, pageNum, pageSize } = this.state
    this.setState({
      tLoading: true,
    })
    getData().get(recentTx.format({ consortiumId, channelId, pageNum, pageSize })).then(res => {
      if (res.status === 200) {
        let data = res.data.transactions || []
        const totalNum = res.data.totalNum || 0
        if (data.length) {
          data.forEach((item, index) => {
            item.No = totalNum - index
          })
        }
        this.setState({
          txData: data,
          tLoading: false,
          txTotalNum: totalNum,
        })
      }
    })
  }

  moreFn = (type) => {
    const { consortiumId, consortiumName, channelId } = this.state
    let pathname = ''
    if (!channelId) return false
    if (type === 'block') {
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/allBlock/${channelId}`
    } else {
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/allTransactions/${channelId}`
    }
    this.props.history.push({
      pathname,
    })
  }

  // 表格跳转
  clickRowFn = (event, type, data) => {
    const { consortiumId, channelId, consortiumName } = this.state
    let pathname = ''
    if (type === 'block') {
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/blockDetail/${channelId}/${data.id || data.uuid}`
    } else {
      pathname = `/dashboard/fabric/leagueInfo/${consortiumId}/${consortiumName}/transactionsDetail/${channelId}/${data.id || data.uuid}`
    }

    this.props.history.push({
      pathname,
    })
  }

  getRender = (data, params, size, loading) => {
    if (loading) return <span><Spin size={size} /></span>
    if (!data) return ''
    if (params === 'consortiumStatus') {
      return <span className={STATUSCLASS[_.get(data, params)]}>{STATUS[_.get(data, params)]}</span>
    } else {
      return <span className="render-params">{_.get(data, params)}</span>
    }
  }

  render() {
    const { channelList, defaultChannel, overviewConf, overviewData, cardConf, tableConf, overviewLoading } = this.state
    return (
      <div className="browser-page common">
        <div className="browser-operate">
          <Select
            value={defaultChannel || null}
            style={{ width: 200 }}
            onChange={this.changeChannel}
            placeholder="切换通道"
            suffixIcon={<div className="channel-suffix"><CaretDownOutlined /></div>}
          >
            {
              channelList.length ? channelList.map(item => {
                return (
                  <Option key={item.name} value={item.name}>{item.name}</Option>
                )
              }) : ''
            }
          </Select>
          {/* <Button className="com-btn-secondary com-normal-btn" onClick={() => { this.props.history.push({ pathname: `/monitor/${consortiumId}` }) }}>大屏模式<DoubleRightOutlined /></Button> */}
          <SearchInput placeholder="请输入序号或TxHash" search={this.queryNoHash}/>
        </div>
        <div className="browser-overview">
          {
            overviewConf.map(element => {
              return (
                <div key={element.params} className="overview-item">
                  <span className="overview-label">{element.label}</span>
                  {this.getRender(overviewData, element.params, 'small', overviewLoading)}
                </div>
              )
            })
          }
        </div>
        <div className="browser-card">
          {
            cardConf.map(element => {
              return (
                <div key={element.params} className="card-item">
                  <img src={element.icon} alt="" />
                  <span className="card-label">{element.label}</span>
                  {this.getRender(overviewData, element.params, 'large', overviewLoading)}
                </div>
              )
            })
          }
        </div>
        <div className="browser-table">
          {
            tableConf.map(element => {
              return (
                <div key={element.type} className="table-item">
                  <div className="table-title">
                    {element.title}
                    {
                      this.state[element.total] > 5 &&
                      <span className="more-btn"
                        onClick={() => { this.moreFn(element.type) }}>查看更多<DoubleRightOutlined />
                      </span>
                    }
                  </div>
                  <Table
                    rowKey={element.key}
                    columns={this.state[element.cloumn]}
                    dataSource={this.state[element.dataName]}
                    loading={this.state[element.loading]}
                    pagination={false}
                    onRow={record => {
                      return {
                        onClick: (event) => { this.clickRowFn(event, element.type, record) }, // 点击行
                      }
                    }}
                  />
                </div>
              )
            })
          }
        </div>
      </div>
    )
  }
}

const STATUS = {
  'SUCCESS': '运行中',
  'FAIL': '失败',
}

const blockCloumn = [
  {
    title: '区块号',
    dataIndex: 'height',
    sorter: {
      compare: (a, b) => a.height - b.height,
      multiple: 2,
    },
  },
  {
    title: '区块哈希',
    dataIndex: 'data_hash',
    render: (text) => (
      <span>{text ? text.slice(0, 10) + '...' + text.slice(-3) : '--'}</span>
    ),
  },
  {
    title: '交易数',
    dataIndex: 'tx_number',
  },
  {
    title: '生成时间',
    dataIndex: 'timestamp',
    render: (text) => (
      <span>{moment(text).format(APP_TIMESTAMP_FORMAT)}</span>
    ),
    sorter: {
      compare: (a, b) => moment(a.timestamp).valueOf() - moment(b.timestamp).valueOf(),
      multiple: 1,
    },
  },
]

const txCloumn = [
  {
    title: '序号',
    dataIndex: 'No',
    sorter: {
      compare: (a, b) => a.No - b.No,
      multiple: 2,
    },
  },
  {
    title: '交易哈希',
    dataIndex: 'tx_hash',
    render: (text) => (
      <span>{text ? text.slice(0, 18) + '...' + text.slice(-3) : '--'}</span>
    ),
  },
  {
    title: '生成时间',
    dataIndex: 'timestamp',
    render: (text) => (
      <span>{moment(text).format(APP_TIMESTAMP_FORMAT)}</span>
    ),
    sorter: {
      compare: (a, b) => moment(a.timestamp).valueOf() - moment(b.timestamp).valueOf(),
      multiple: 1,
    },
  },
]

export default BlockchainBrowser
